1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.google.common.collect;
18
19 import static com.google.common.base.Preconditions.checkArgument;
20 import static com.google.common.base.Preconditions.checkNotNull;
21
22 import com.google.common.annotations.GwtCompatible;
23
24 import java.util.EnumMap;
25 import java.util.Map;
26
27
28
29
30
31
32
33
34
35
36
37
38
39 @GwtCompatible(emulated = true)
40 public final class EnumBiMap<K extends Enum<K>, V extends Enum<V>>
41 extends AbstractBiMap<K, V> {
42 private transient Class<K> keyType;
43 private transient Class<V> valueType;
44
45
46
47
48
49
50
51
52 public static <K extends Enum<K>, V extends Enum<V>> EnumBiMap<K, V>
53 create(Class<K> keyType, Class<V> valueType) {
54 return new EnumBiMap<K, V>(keyType, valueType);
55 }
56
57
58
59
60
61
62
63
64
65
66
67 public static <K extends Enum<K>, V extends Enum<V>> EnumBiMap<K, V>
68 create(Map<K, V> map) {
69 EnumBiMap<K, V> bimap = create(inferKeyType(map), inferValueType(map));
70 bimap.putAll(map);
71 return bimap;
72 }
73
74 private EnumBiMap(Class<K> keyType, Class<V> valueType) {
75 super(WellBehavedMap.wrap(new EnumMap<K, V>(keyType)),
76 WellBehavedMap.wrap(new EnumMap<V, K>(valueType)));
77 this.keyType = keyType;
78 this.valueType = valueType;
79 }
80
81 static <K extends Enum<K>> Class<K> inferKeyType(Map<K, ?> map) {
82 if (map instanceof EnumBiMap) {
83 return ((EnumBiMap<K, ?>) map).keyType();
84 }
85 if (map instanceof EnumHashBiMap) {
86 return ((EnumHashBiMap<K, ?>) map).keyType();
87 }
88 checkArgument(!map.isEmpty());
89 return map.keySet().iterator().next().getDeclaringClass();
90 }
91
92 private static <V extends Enum<V>> Class<V> inferValueType(Map<?, V> map) {
93 if (map instanceof EnumBiMap) {
94 return ((EnumBiMap<?, V>) map).valueType;
95 }
96 checkArgument(!map.isEmpty());
97 return map.values().iterator().next().getDeclaringClass();
98 }
99
100
101 public Class<K> keyType() {
102 return keyType;
103 }
104
105
106 public Class<V> valueType() {
107 return valueType;
108 }
109
110 @Override
111 K checkKey(K key) {
112 return checkNotNull(key);
113 }
114
115 @Override
116 V checkValue(V value) {
117 return checkNotNull(value);
118 }
119 }
120